<template>
  <view class="speak-container">
    <template v-if="!isSpeaking">
      <template v-if="!isSetSlot">
        <view class="scene-operate">
          <slot name="prefix-icon"></slot>
          <image class="scene-switch" v-if="props.prevIconUrl" :src="props.prevIconUrl" @click="handleToPrev" />
          <button :disabled="disabled" :class="['scene-speak', disabled && 'disabled']"
            :style="{ width: props.isShowSubBtn ? '13rem' : '15rem' }" @click="handleSpeaking">
            <image class="speak-icon" :style="{ marginRight: props.isShowSubBtn ? '0.8rem' : '1.2rem' }"
              :src="props.speakIcon" />
            <text class="speak-label">{{ props.title }}</text>
          </button>
          <image class="scene-switch" v-if="props.nextIconUrl" :src="props.nextIconUrl" @click="handleToNext" />

          <button v-if="props.isShowSubBtn" class="scene-sub-speak" @click="handleSubClick">
            {{ props.subTitle }}
          </button>
        </view>
      </template>
      <slot name="main-button" :slot-event="handleSetSlotEvent"></slot>
    </template>

    <view class="scene-speaking" v-if="isSpeaking">
      <view class="speaking-wrapper">
        <view class="speaking-btn">
          <image class="icon" src="https://rwstatic.tentons.cn/web/Lesson/images/time-icon.png" />
          <text class="label">{{ speakTime }}s</text>
        </view>
        <text class="speaking-label">点击波纹，结束录音</text>
        <view class="speaking-btn" @click="handleReSpeaking">
          <image class="icon" src="https://rwstatic.tentons.cn/web/Lesson/images/replay-icon.png" />
          <text class="label">重录</text>
        </view>
      </view>
      <image class="speaking-wavy" src="https://rwstatic.tentons.cn/web/Lesson/images/speaking-wavy.png"
        @click="handleStopSpeaking" />
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, onBeforeUnmount } from "vue";
import { Recorder } from "@/utils/recorder";
// @ts-ignore
import { ossUpload } from "@/utils/oss/oss.js";
import { util } from "@/utils/util";

interface IProps {
  title: string;
  disabled?: boolean,// 是否禁用按钮
  subTitle?: string;
  isShowSubBtn?: boolean;
  prevIconUrl?: string; // prev切换按钮
  nextIconUrl?: string; // next切换按钮
  speakIcon?: string;
  speakStyle?: any;
  isSetSlot?: boolean;
}

export interface IUploadSuccessInfo {
  localFilePath: string;
  ossFilePath: string;
}

const props = withDefaults(defineProps<IProps>(), {
  title: "朗读选项",
  subTitle: "继续",
  isShowSubBtn: false,
  speakIcon: "https://rwstatic.tentons.cn/web/Lesson/images/speak.png",
  isSetSlot: false,
  disabled: false,
});

const emits = defineEmits<{
  (e: "prev"): void;
  (e: "next"): void;
  (e: "mainClick"): void;
  (e: "subClick"): void;
  (e: "onStartUpload"): void;
  (e: "onUploadSuccess", info: IUploadSuccessInfo): void;
}>();

var recorder: Recorder;

let timer: number | undefined;
const speakTime = ref(0);
const isSpeaking = ref(false);
const fullAudioSrc = ref<string | null>(null);
const isWaitStart = ref(false);

const getRecorder = () => {
  if (!recorder) {
    recorder = new Recorder();
  }
  return recorder;
};

const handleStartRecorder = () => {
  getRecorder().start({
    onStart: () => {
      isWaitStart.value = false;
      isSpeaking.value = true;
      timer = setInterval(() => {
        speakTime.value += 1;
      }, 1000);
    },
    onSuccess: (res) => {
      fullAudioSrc.value = res.fullFilePath;
      emits("onStartUpload");

      ossUpload(res.fullFilePath).then((val: any) => {
        console.log("上传成功", val);
        emits("onUploadSuccess", { localFilePath: res.fullFilePath, ossFilePath: `front-course/h5/${val.data.fileName}` });
      });
    },
    onFail: (errorMsg) => {
      isWaitStart.value = false;
      util.showDialogue("录音失败:" + errorMsg);
    },
    onComplete: () => {
      clearInterval(timer);
      speakTime.value = 0;
      isSpeaking.value = false;
    },
  });
};

const handleSubClick = () => {
  emits("subClick");
};

const handleToNext = () => {
  emits("next");
}

const handleToPrev = () => {
  emits("prev");
}

const handleSpeaking = () => {
  if (isWaitStart.value) {
    return;
  }
  isWaitStart.value = true;
  emits("mainClick");
  handleStartRecorder();
};

const handleReSpeaking = () => {
  getRecorder().cancel(() => {
    clearInterval(timer);
    speakTime.value = 0;
    fullAudioSrc.value = "";
    setTimeout(() => {
      handleStartRecorder();
    }, 500);
  });
};

const handleStopSpeaking = () => {
  getRecorder().stop();
};

const handleSetSlotEvent = (val: string) => {
  if (val === "reRecord") {
    handleSpeaking();
  }
}

onBeforeUnmount(() => {
  getRecorder().cancel(() => { });
  clearInterval(timer);
  speakTime.value = 0;
});
</script>

<style scoped lang="scss">
.speak-container {
  width: 100%;

  .scene-operate {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    bottom: 4.7rem;
    left: 0;
    right: 0;
    height: 5rem;
    padding: 0 4.6rem;

    .is-hover {
      color: rgba(255, 255, 255, 0.6);
    }

    .scene-speak {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 15rem;
      height: 5rem;
      padding: 0;
      border-radius: 1rem;
      background-color: $uni-bg-color-speak;
      border: 2px solid $uni-border-speak-color;

      &.disabled {
        background-color: rgba(216, 171, 96, .5);
      }

      .speak-icon {
        width: 2.8rem;
        height: 2.8rem;
      }

      .speak-label {
        font-size: 1.7rem;
        font-family: xiaolai;
        font-weight: 400;
        color: #ffffff;
      }
    }

    .scene-switch {
      width: 3rem;
      height: 3rem;
    }

    .scene-sub-speak {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 13rem;
      height: 5rem;
      border-radius: 1rem;
      font-size: 1.7rem;
      font-family: xiaolai;
      font-weight: 400;
      color: $uni-text-color;
      background-color: $uni-btn-prime;
      border: 2px solid $uni-btn-border;
    }
  }

  .scene-speaking {
    position: fixed;
    height: 12.5rem;
    bottom: 0;
    right: 0;
    left: 0;
    background-color: #ffffff;

    .speaking-wrapper {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 0 3rem;
      margin-bottom: 3rem;

      .speaking-btn {
        display: flex;
        align-items: center;

        .icon {
          width: 1.8rem;
          height: 1.8rem;
          margin-right: 0.2rem;
        }

        .label {
          font-size: 1.4rem;
          font-family: xiaolai;
          color: $uni-text-color-btn;
        }
      }

      .speaking-label {
        font-size: 1.4rem;
        font-family: xiaolai;
        color: $uni-text-color-grey;
      }
    }

    .speaking-wavy {
      width: 100%;
      height: 3rem;
    }
  }
}
</style>
